
package andre.grids.util;

/**
 *
 * @author andre
 */
public final class FastStringArray {
    private String[] data;
    private int usedData;
    
    /**
     * Inicializa o objeto com a capacidade inicial informada
     * @param capacity Capacidade inicial desejada
     */
    public FastStringArray(int capacity) {
        data = new String[capacity];
        usedData = 0;
    }
    
    /**
     * Inicializa o objeto com um tamanho padrão de 20 unidades
     */
    public FastStringArray() {
        this(20);
    }
    
    /**
     * Adiciona um item à lista.
     * @param obj O objeto a ser colocado no vetor
     * @return o objeto this para encadeamento
     */
    public final FastStringArray add(String obj) {
        if (usedData == data.length)
            growArray();
        data[usedData++] = obj;
        return this;
    }
    
    /**
     * 
     * @param index indice do objeto desejado
     * @return o item na posição
     */
    public final String itemAt(int index) {
        if (index < usedData)
            throw new IndexOutOfBoundsException("Indice " + index + " inválido");
        return data[index];
    }
    
    /**
     * Retorna o vetor de strings
     * @return retorna o vetor de strings
     */
    public final String[] toArray() {
        String[] result = new String[usedData];
        System.arraycopy(data, 0, result, 0, usedData);
        return result;        
    }
    
    /**
     * Reduz o tamanho do vetor para ocupar apenas a quantidade de memória que está sendo utilizada.
     * Chama o System.gc() para liberar a memória que foi alocada anteriormente
     * @return o objeto this para encadeamento das chamadas
     */
    public FastStringArray trim() {
        String [] trimmed = new String[usedData];
        System.arraycopy(data, 0, trimmed, 0, usedData);
        data = trimmed;
        System.gc();
        return this;
    }
    
    /**
     * Aumenta o tamanho do vetor interno para armazenar o dobro do tamanho antigo
     */
    private final void growArray() {
        String [] newArray = new String[data.length*2];
        System.arraycopy(data, 0, newArray, 0, usedData);
        data = newArray;
        System.gc();
    }

    /**
     * Forca uma chamada ao System.gc() para liberar o espaço
     * alocado para as strings, pois a coleção pode ser muito grande
     * e ficar ocupando espaço em memória.
     * */
    @Override
    protected void finalize() throws Throwable {
        data = null;
        usedData = 0;
        System.gc();
    }
    
}
